import pickle  # 数据持久化

all_users = []  # 存放用户信息(老板等级为 1；经理等级为 2;员工等级为 3)
boss_goods = []  # 存放货物信息


class Goods:  # 创建货物类
    def __init__(self, number: int, name: str, amount: int, price: float):
        self.number = number  # 货物编号
        self.name = name  # 货物名称
        self.amount = amount  # 货物数量
        self.price = price  # 货物价格

    def __str__(self):  # 创建新方法，方便打印
        return "货物编号: {}, 货物名称: {}, 货物数量: {}, 货物价格: {}".format(self.number, self.name, self.amount, self.price)


class Staff:  # 创建员工类
    def __init__(self, user_name: str, pass_pw: str, permission: int, authorization: int, belong: str):
        if user_name == "lzy":
            print("你敢用老板账号？")
        else:
            self.user_name = user_name  # 员工账号
            self.pass_pw = pass_pw  # 员工密码
            self.permission = permission  # 员工等级
            self.authorization = authorization  # 员工权限
            self.belong = belong  # 员工归属

    def __str__(self):  # 创建新方法，方便打印
        return "员工账号： {}，员工密码： {}，员工等级： {}，员工权限： {}，员工归属： {}".format(self.user_name, self.pass_pw, self.permission,
                                                                     self.authorization, self.belong)

    def view_goods(self):  # 查看货物
        # 验证权限
        if self.authorization & 0b0001 == 1:
            for item in boss_goods:
                print(item)
        else:
            print("很抱歉，你没有商品查看权限！")

    def add_goods(self):  # 添加货物
        # 验证权限
        if self.authorization & 0b0010 == 2:
            number = int(input("请输入要添加商品编号:"))
            for item in boss_goods:
                if item.number == number:
                    print("商品编号{}已存在,请重新选择！".format(item.number))
                    break
            else:
                name = input("请输入添加商品名称:")
                price = round(float(input("请输入添加商品价格:")), 2)
                amount = int(input("请输入添加商品数量:"))
                item = Goods(int(number), name, price, amount)
                boss_goods.append(item)
                with open(self.belong + "_goods.txt", "wb+") as file:
                    pickle.dump(boss_goods, file)
                print("商品编号{}添加成功！".format(number))
        else:
            print("很抱歉，你没有商品添加权限！")

    def sale_goods(self):  # 销售货物
        number = int(input("请输入售卖的商品编号:"))
        for info in boss_goods:
            if info.number == number:
                amount = int(input("请输入商品的售卖的数量："))
                info.amount -= amount
                with open(self.belong + "_goods.tx", "wb+") as file:
                    pickle.dump(boss_goods, file)
                print("{}商品成功售出{}件,交易金额{}元.".format(info.name, amount, amount * info.price))
                break
        else:
            print("你输入的商品信息有误！")

    def del_goods(self):  # 删除货物
        # 验证权限
        if self.authorization & 0b0100 == 4:
            number = int(input("请输入要删除的商品编号："))
            for item in boss_goods:
                if item.number == number:
                    boss_goods.remove(item)
                    with open(self.belong + "_goods.txt", "wb+") as file:
                        pickle.dump(boss_goods, file)
                    print("商品{}删除成功".format(number))
                    break
            else:
                print("商品{}不存在".format(number))
        else:
            print("很抱歉，你没有商品删除权限！")


def staff(soma):  # 员工程序
    global boss_goods
    user = soma.__dict__["user_name"]
    file_name = soma.belong + "_goods.txt"
    try:
        with open(file_name, "rb+") as file:
            boss_goods = pickle.load(file)  # 尝试从文件载入本超市所有商品到临时列表
    except Exception as x:  # 如果文件为空会报错，此处为异常处理
        test_item = Goods(0, "test", 0.0, 0)  # 创建测试商品，避免出错
        boss_goods.append(test_item)  # 列表保存测试商品
        with open(file_name, "wb+") as file:
            pickle.dump(boss_goods, file)  # 存储货物对象的列表改动了，文件就要重新写入刷新一次
    while True:
        print('''
                  员工账号{}登录成功
                   欢迎进入员工程序
                     1.查看货物
                     2.添加货物
                     3.销售货物
                     4.删除货物
                     5.退出程序
        '''.format(user))
        num = input("请输入指令： ")
        if num == "1":
            soma.view_goods()
        elif num == "2":
            soma.add_goods()
        elif num == "3":
            soma.sale_goods()
        elif num == "4":
            soma.del_goods()
        elif num == "5":
            break
        else:
            print("你输入的指令错误，请重新输入！")


class Boss(Staff):  # 创建经理类,继承员工的方法
    def __init__(self, user_name: str, pass_pw: str):
        if user_name == "lzy":
            print("你敢用老板的账号？")
        else:
            self.user_name = user_name
            self.pass_pw = pass_pw
            self.permission = 2
            self.authorization = 7
            self.belong = user_name

    def __str__(self):
        return "经理账号: {},经理密码：{}，经理等级： {}，经理权限：{}".format(self.user_name, self.pass_pw, self.permission,
                                                          self.authorization)

    def change_own_pd(self):  # 修改经理密码
        all_users.remove(self)
        new_pd = input("请输入新密码: ")
        self.pass_pw = new_pd
        all_users.append(self)
        with open("all_users.txt", "rb+") as file:
            pickle.dump(all_users, file)
        print("经理{}账户密码修改成功,请牢记新密码!".format(self.user_name))

    def creat_staff(self):  # 创建员工账号
        user_name = input("请输入你要创建的员工账户名: ")
        for info in all_users:
            if user_name == info.user_name:
                print("{}账户已存在!".format(user_name))
                break
        else:
            pass_pw = input("请设置密码：")
            permission = 3
            authorization = int(input("请输入商品权限组合数字(0b0001查看,0b0010添加,0b0100删除)："))
            belong = self.user_name
            user_info = Staff(user_name, pass_pw, permission, authorization, belong)
            all_users.append(user_info)
            with open("all_users.txt", "rb+") as file:
                pickle.dump(all_users, file)
            print("员工账户{}添加成功!".format(user_name))

    def del_staff(self):  # 删除员工账户
        user_name = input("请输入你要删除的员工账号： ")
        for info in all_users:
            if user_name == info.user_name:
                if info.belong == self.user_name:
                    all_users.remove(info)
                    with open("all_users.txt", "rb+") as file:
                        pickle.dump(all_users, file)
                    print("员工账户{}删除成功".format(user_name))
                    break
                else:
                    print("你输入的帐号不属于本超市！")
            else:
                print("员工账户{}不存在".format(user_name))

    def view_staff(self):  # 查看员工账户
        for info in all_users:
            if info.belong == self.user_name:  # 是自己店铺的员工才显示
                print(info)

    def accredit_staff(self):  # 给员工重新授权
        user_name = input("请输入要重新授权的员工账户：")
        for info in all_users:
            if info.user_name == user_name and info.permission == 3:
                a = input("请输入货物权限数字(1查看，2添加,4删除)：")
                info.authorization = int(a)
                with open("all_users.txt", "rb+") as file:
                    pickle.dump(all_users, file)
                print("员工{}重新授权成功!".format(info.user_name))
                break
        else:
            print("员工账户{}不存在".format(user_name))


def boss_shop(boss):  # 经理专属的商品操作程序
    global boss_goods
    user = boss.__dict__["user_name"]
    try:
        with open(user + "_goods.txt", "rb+") as file:
            boss_goods = pickle.load(file)  # 尝试从文件载入《本超市》所有商品到临时货物列表
    except Exception as x:  # 如果文件为空会报错，此为异常处理
        test_item = Goods(0, "test", 0.0, 0)  # 创建测试商品，避免出错
        boss_goods.append(test_item)  # 列表保存测试商品
        with open(user + "_goods.txt", "wb+") as file:
            pickle.dump(boss_goods, file)  # 保存货物的列表改动一次，文件就刷新一次
    while True:
        print(
            '''
                                 {},欢迎进入您的商品管理程序！
                                  1.查看货物
                                  2.添加货物
                                  3.销售货物
                                  4.删除货物
                                  5.回到上一级
            '''.format(boss.__dict__["user_name"]))
        num = input("请输入操作指令：")
        if num == "1":
            boss.view_goods()
        elif num == "2":
            boss.add_goods()
        elif num == "3":
            boss.sale_goods()
        elif num == "4":
            boss.del_goods()
        elif num == "5":
            break
        else:
            print("你输入的指令有误,请重新输入！")


def boss(boss):  # 经理程序
    while True:
        print('''
                   经理{}账户登录成功
                   1.修改经理密码
                   2.创建员工账户
                   3.删除员工账户
                   4.查看员工账户
                   5.给员工重新授权
                   6.进入经理商品程序
                   7.退出经理程序
        '''.format(boss.__dict__["user_name"]))

        num = input("请输入操作指令: ")
        if num == "1":
            boss.change_own_pd()
        elif num == "2":
            boss.creat_staff()
        elif num == "3":
            boss.del_staff()
        elif num == "4":
            boss.view_staff()
        elif num == "5":
            boss.accredit_staff()
        elif num == "6":
            boss_shop(boss)
        elif num == "7":
            break
        else:
            print("你输入的指令有误，请重新输入！")


class Big_boss:  # 创建老板类
    def __init__(self, user_name: str, pass_pw: str):  # 创建老板账户
        for info in all_users:
            if info.user_name == "lzy":
                print("老板只有一个！")
        else:
                self.user_name = "lzy"
                self.pass_pw = "lzy"
                self.permission = 1
                self.belong = " "
                print("查无此账号，老板账号创建成功呦，亲！")

    def change_own_pd(self):  # 修改老板密码
        all_users.remove(self)
        new_pd = input("请输入新密码: ")
        self.pass_pw = new_pd
        all_users.append(self)
        with open('all_users.txt', 'rb+') as file:
            pickle.dump(all_users, file)
        print("修改密码成功！")

    def create_boss(self):  # 创建经理账户
        user_name = input("请输入你要创建的经理账号名: ")
        for info in all_users:
            if info.user_name == user_name:
                print("{}账号已存在！".format(user_name))
                break
            else:
                pass_pw = input("请设置密码: ")
                user_info = Boss(user_name, pass_pw)
                all_users.append(user_info)
                with open('all_users.txt', 'rb+') as file:
                    pickle.dump(all_users, file)
                print('经理账户{}添加成功'.format(user_name))

    def del_boss(self):  # 删除经理账户
        user_name = input("请输入您要删除的经理账号: ")
        for info in all_users:
            if info.user_name == user_name and info.permission == 2:
                all_users.remove(info)
                with open('all_users.txt', 'rb+') as file:
                    pickle.dump(all_users, file)
                print('经理账户{}删除成功'.format(user_name))
                break
        else:
            print('经理账户{}不存在'.format(user_name))

    def view_boss(self):  # 查看所有经理
        for info in all_users:
            if info.permission == 2:
                print(info)


def big_boss(boss):  # 老板程序
    while True:
        print('''
                     老板账户boss登录成功
                       欢迎进入老板程序
                       1.修改老板密码
                       2.创建经理账户
                       3.删除经理账户
                       4.查看所有经理
                       5.退出老板程序
        ''')
        num = input("请输入指令: ")
        if num == "1":
            boss.change_own_pd()
        elif num == "2":
            boss.create_boss()
        elif num == "3":
            boss.del_boss()
        elif num == "4":
            boss.view_boss()
        elif num == "5":
            break
        else:
            print("你输入的指令错误，请重新输入！")


def login():  # 输入不同的帐号会进入不同的程序(分别是老板的后台程序，经理的后台程序，员工的后台程序)
    print("═══════════════现已进入登录程序═══════════════")
    user_name = input("请输入帐号：")
    pass_pw = input("请输入密码：")
    not_in = True
    for info in all_users:  # 遍历内存中存储所有账号的列表
        if info.user_name == user_name and info.pass_pw == pass_pw:
            if info.permission == 1:  # 判断为老板账户，进入老板程序
                big_boss(info)  # 老板对象作为参数传进去
                not_in = False
            elif info.permission == 2:  # 判断为经理账户，进入经理自己的后台程序
                boss(info)  # 经理对象作为参数传进去
                not_in = False
            elif info.permission == 3:  # 判断为员工程序，进入员工所属的超市商品管理系统
                staff(info)  # 员工对象作为参数传进去
                not_in = False
    if not_in:
        print("系统中无此帐号或密码错误，请重新输入！")


def main():
    while True:
        print("═══════════════现已进入主程序═══════════════")
        login()
        is_exit = input("你当前处于主程序，本次是否完全退出（y/n）:")
        if is_exit.upper() == 'Y':
            exit()


if __name__ == "__main__":
    try:  # 尝试从文件载入所有账户信息到列表
        with open("all_users.txt", "rb+") as file:
            all_users = pickle.load(file)  # 所有用户信息读取到临时列表
    except Exception as x:  # 如果文件为空会报错，处理异常程序
        boss0 = Big_boss("lzy", "lzy")  # 创建老板账户
        all_users.append(boss0)  # 列表添加这个老板对象
        with open("all_users.txt", "wb+") as file:
            pickle.dump(all_users, file)  # 临时列表每次改动，都要重新写入文件

    main()
